<html>
<head>
<title>Engima Test Page</title>
<script src="namespace.js"></script>
<script src="base.js"></script>
<script src="mersene_twister.js"></script>
<script src="random.js"></script>
<script src="formatutil.js"></script>
<script src="enigma.js"></script>
<script src="vector.js"></script>
<script src="timer.js"></script>
<script src="unit.js"></script>
</head>
<body>
<h1><script>document.write(document.title);</script></h1>
<SCRIPT>
var UT = global_namespace.Import('startpad.unit');
var ts = new UT.TestSuite();
ts.DWOutputDiv();
</script>
<script>
var Enigma = global_namespace.Import('startpad.enigma');
var Random = global_namespace.Import('startpad.random');
var Vector = global_namespace.Import('startpad.vector');
Enigma.fnTrace = function(s) {console.log(s);}

ts.AddTest("Basic Reciprocal Encoding", function(ut)
{
	var machine = new Enigma.Enigma();
	var cipher = machine.Encode("plain text");
	machine.Init();
	var plain = machine.Encode(cipher);
	
	ut.AssertEq(plain, "PLAIN TEXT");
});

ts.AddTest("Sample Config", function(ut)
{
	var aTests = [
		["ENIGMA REVEALED", "QMJIDO MZWZJFJR"],
		["QMJIDO PQDPSRJLCV", "ENIGMA AUFGEDECKT"]
		];
		
	var enigma = new Enigma.Enigma();
		
	for (var i in aTests)
		{
		ut.AssertEq(enigma.Encode(aTests[i][0]), aTests[i][1]);
		enigma.Init();
		ut.AssertEq(enigma.Encode(aTests[i][1]), aTests[i][0]);
		enigma.Init();
		}
});

ts.AddTest("Rotor Motion", function(ut)
{	
	var enigma = new Enigma.Enigma();
	enigma.Init({position:['A', 'D', 'V']});
	ut.AssertEq(enigma.toString(), "Enigma Rotors: I-II-III Position: ADV");
	
	ut.AssertEq(enigma.Encode("A"), "Q");
	ut.AssertEq(enigma.toString(), "Enigma Rotors: I-II-III Position: AEW");
	ut.AssertEq(enigma.Encode("A"), "I");
	ut.AssertEq(enigma.toString(), "Enigma Rotors: I-II-III Position: BFX");
	ut.AssertEq(enigma.Encode("A"), "B");
	ut.AssertEq(enigma.toString(), "Enigma Rotors: I-II-III Position: BFY");
	
	enigma.Init();
	ut.AssertEq(enigma.Encode("AA"), "QI");
	ut.AssertEq(enigma.toString(), "Enigma Rotors: I-II-III Position: BFX");
});

ts.AddTest("Ring Settings", function(ut)
{
	var enigma = new Enigma.Enigma();
	
	enigma.Init({position:['A', 'A', 'A']});
	ut.AssertEq(enigma.toString(), "Enigma Rotors: I-II-III Position: AAA");
	ut.AssertEq(enigma.Encode("AAA"), "BDZ");
	
	enigma.Init({rings: ['A', 'A', 'B']});
	ut.AssertEq(enigma.toString(), "Enigma Rotors: I-II-III Position: AAA Rings: AAB");
	ut.AssertEq(enigma.Encode("AAA"), "UBD");
	enigma.Init({position: ['A', 'A', 'U']});
	ut.AssertEq(enigma.toString(), "Enigma Rotors: I-II-III Position: AAU Rings: AAB");
	ut.AssertEq(enigma.Encode("AAA"), "BTU");
});

ts.AddTest("Plugboard Settings", function(ut)
{
	var enigma = new Enigma.Enigma();
	
	enigma.Init({plugs:"AB CD E-F"});
	ut.AssertEq(enigma.toString(), "Enigma Rotors: I-II-III Position: MCK Plugboard: AB CD EF");
	var cipher = enigma.Encode("ABCDEF");
	enigma.Init();
	ut.AssertEq(enigma.Encode(cipher), "ABCDEF");
});

ts.AddTest("Settings From Strings", function(ut)
{
	var enigma = new Enigma.Enigma();
	
	var mState = enigma.StateStrings();
	ut.AssertEq(mState, {
		rotors: "I-II-III",
		reflector: "B",
		position: "MCK",
		rings: "AAA",
		plugs: ""
		});
		
	mState = {
		rotors: "III-II-I",
		reflector: "C",
		rings: "XYZ",
		position: "UVW",
		plugs: "AB CD"
		};
		
	var mSettings = Enigma.SettingsFromStrings(mState);
	console.log(mSettings);
	enigma.Init(mSettings);
	
	ut.AssertEq(enigma.toString(),
		"Enigma Rotors: III-II-I Position: UVW Rings: XYZ Plugboard: AB CD");
});

ts.AddTest("Group Letters", function(ut)
{
	ut.AssertEq(Enigma.GroupLetters("a"), "A");
	ut.AssertEq(Enigma.GroupLetters("aaaaa"), "AAAAA");
	ut.AssertEq(Enigma.GroupLetters("aaaaaa"), "AAAAA A");
	ut.AssertEq(Enigma.GroupLetters("aaaaaaaaaaaaaa"), "AAAAA AAAAA AAAA");
	
});

ts.AddTest("Settings from Passkey", function(ut)
{
	var settings = Enigma.SettingsFromPasskey("");
	ut.AssertEq(settings.rotors.length, 3);
	ut.AssertEq(settings.position.length, 3);
	ut.AssertEq(settings.rings.length, 3);
});

ts.AddTest("Cycle Length", function(ut)
{
	var machine = new Enigma.Enigma();
	var posStart = machine.position.concat();
	var i = 0;
	
	while (true)
		{
		i += 1;
		machine.IncrementRotors();
		if (Vector.Equal(posStart, machine.position))
			break;
		}
		
	ut.AssertEq(i, 26*26*25);
});

ts.Run();
ts.Report();

</script>
</body>
</html>
